//-----------------------------------------------------------------------------------------------------//
//																	                                   //
// cartesian_plane.cpp  contains implementation	of the cartesian plane								   //
//																									   //
// author	: Eng. Ahmed Yasser																		   //
// data		: 21-01-2015																			   //
//																	                                   //
//-----------------------------------------------------------------------------------------------------//
#include "..\include\cartesian_plane.h"
#include "..\include\number_line.h"

cartesian_plane_t create_cartesian_plane(float x, float y, float sx, float sy, unsigned int lx, unsigned int ly)
{
	cartesian_plane_t car_plane;
	car_plane.origin_x = x;
	car_plane.origin_y = y;
	car_plane.step_x = sx;
	car_plane.step_y = sy;
	car_plane.length_x = lx;
	car_plane.length_y = ly;

	car_plane.draw_info.sx = car_plane.origin_x - car_plane.step_x * car_plane.length_x;
	car_plane.draw_info.ex = car_plane.origin_x + car_plane.step_x * car_plane.length_x;
	car_plane.draw_info.length_x = car_plane.draw_info.ex - car_plane.draw_info.sx;

	car_plane.draw_info.sy = car_plane.origin_y - car_plane.step_y * car_plane.length_y;
	car_plane.draw_info.ey = car_plane.origin_y + car_plane.step_y * car_plane.length_y;
	car_plane.draw_info.length_y = car_plane.draw_info.ey - car_plane.draw_info.sy;

	return car_plane;
}

void transform_to_cartesian_plane(const cartesian_plane_t& cp)
{
	// scale the model to display the cartesian plane
	glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
	glScaled(1.0 / (cp.draw_info.length_x / 2.0), 1.0 / (cp.draw_info.length_y / 2.0), 1.0);
}

void draw_cartesian_plane(const cartesian_plane_t& cp, float r, float g, float b, float a)
{
	// transform to the cartesian plane
	transform_to_cartesian_plane(cp);

	// create the axis lines
	number_line_t horiz_line = create_number_line(cp.origin_x, cp.origin_y, cp.step_x, cp.length_x);
	number_line_t vert_line = create_number_line(cp.origin_x, cp.origin_y, cp.step_y, cp.length_y, true);

	// draw the lines
	draw_number_line(horiz_line, r, g, b, a);
	draw_number_line(vert_line, r, g, b, a);	
}

void draw_ordered_pair(ordered_pair pair, const cartesian_plane_t& cp, float r, float g, float b, float a, bool dis_info)
{
	// transform to the cartesian plane
	transform_to_cartesian_plane(cp);

	// draw the pair
	draw_point(pair.x + cp.origin_x, pair.y + cp.origin_y, r, g, b, a);

	if (dis_info)
	{
		// draw the number string
		draw_string(false, print_ordered_pair(pair).c_str(), pair.x + cp.origin_x + cp.draw_info.length_x / 200.0f, 
					pair.y + cp.origin_y + cp.draw_info.length_y / 200.0f, r, g, b, a);
	}
}

void draw_ordered_pairs(std::vector<ordered_pair> pairs, const cartesian_plane_t& cp, float r, float g, float b, float a, bool dis_info, bool connect)
{	
	for (unsigned int i = 0; i < pairs.size(); i++)
		draw_ordered_pair(pairs[i], cp, r, g, b, a, dis_info);

	// connect the dots
	if (connect)
		for (unsigned int i = 0; i < pairs.size() - 1; i++)
			draw_line(1.0f, pairs[i].x, pairs[i].y, pairs[i+1].x, pairs[i+1].y, r, g, b, a);
}